/**
 *
 */
package xin.xihc.demo.controller;

import io.swagger.annotations.ApiImplicitParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.logback.LogbackLoggingSystem;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import xin.xihc.demo.dao.UserTestDao;
import xin.xihc.demo.form.ListForm;
import xin.xihc.demo.model.StatusEnum;
import xin.xihc.demo.model.UserTest;
import xin.xihc.demo.result.Birthday;
import xin.xihc.jba.core.PageInfo;
import xin.xihc.jba.sql.Select;
import xin.xihc.jba.sql.Where;
import xin.xihc.jba.sql.clause.Elt;
import xin.xihc.utils.common.CommonUtil;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author xihc
 * @version 1.0
 * @date 2018年09月04日
 * @since 1.0
 */
@RestController
@RequestMapping("/test")
public class TestController {

    private static Logger LOGGER = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private UserTestDao userTestDao;

    @GetMapping("/add")
    @Transactional
    public Object add() {
        UserTest user = new UserTest();
        user.setAge(10);
        user.setName("李四");
        user.setBirDate(new Date());
        user.setBirDate2(new java.sql.Date(System.currentTimeMillis()));
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setDescription("测试插入，测试插入，测试插入，测试插入测试插入");
        user.setHeight(180.0F);
        user.setSalary(new BigDecimal(8888));
        user.setWeight(65.00);
        boolean b = userTestDao.add(user);
        UserTest query = new UserTest();
        query.setId(user.getId());
        query.setCreateTime(user.getCreateTime());
        int queryCount = userTestDao.count(query);
        System.err.println(queryCount);
        if (b) {
            return user;
        }
        return "插入失败";
    }

    @GetMapping("/batchAdd")
    public Object batchAdd() {
        UserTest user = new UserTest();
        user.setAge(10);
        user.setName("李四");
        user.setBirDate(new Date());
        user.setBirDate2(new java.sql.Date(System.currentTimeMillis()));
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setDescription("测试插入，测试插入，测试插入，测试插入测试插入");
        user.setHeight(180.0F);
        user.setStatus(StatusEnum.OFFLINE);
        user.setSalary(new BigDecimal(8888));
        user.setWeight(65.00);

        UserTest user1 = new UserTest();
        user1.setAge(12);
        user1.setName("李四ss");
        user1.setBirDate(new Date());
        user1.setBirDate2(new java.sql.Date(System.currentTimeMillis()));
        user1.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user1.setDescription("测试插入，测试插入，测试插入，测试插入测试插入");
        user1.setHeight(180.0F);
        user1.setSalary(new BigDecimal(8888));
        user1.setStatus(StatusEnum.ONLINE);
        user1.setWeight(65.00);
        UserTest[] temp = new UserTest[2];
        temp[0] = user;
        temp[1] = user1;
        userTestDao.batchAdd(new UserTest[]{user, user1});
        int queryCount = userTestDao.count(user);
        System.err.println(queryCount);

        return user;
    }

    @GetMapping("/update/{id}")
    public Object update(@PathVariable String id) {
        UserTest user = new UserTest();
        user.setId(id);
        user.setAge(30);
        user.setName("Leo.Xi");
        user.setBirDate(new Date());
        user.setBirDate2(new java.sql.Date(System.currentTimeMillis()));
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setDescription("测试更新，测试更新，测试更新，测试更新，测试更新，测试更新");
        user.setHeight(1800.0F);
        user.setSalary(new BigDecimal(96567));
        user.setStatus(StatusEnum.OFFLINE);
        user.setWeight(70.00);
        boolean b = userTestDao.update(user);
        if (b) {
            return user;
        }
        userTestDao.updateTest();
        return "更新失败";
    }

    @GetMapping("/delete")
    public Object delete() {
        UserTest user = new UserTest();
        user.setAge(30);
        List<UserTest> list = userTestDao.page(user, UserTest.class, null);
        if (null == list || list.size() < 1) {
            return "该数据不存在";
        }
        boolean b = userTestDao.delete(user);
        if (b) {
            return list;
        }
        return "更新失败";
    }

    @GetMapping("/find/{id}")
    public Object find(@PathVariable String id) {
        UserTest one = userTestDao.findById(id, UserTest.class);
        if (null == one) {
            return "该数据不存在";
        }
        return one;
    }

    @PostMapping("/list")
    public Object list(@RequestBody ListForm form) {
        Where where = new Where();
        Select select = Select.from(UserTest.class).select(UserTest.class).where(where).orderBy("create_time DESC");
        if (CommonUtil.isNotNullEmpty(form.getBirDate())) {
            where.and(new Elt("bir_d1", form.getBirDate()));
        }
        if (CommonUtil.isNotNullEmpty(form.getBirDate2())) {
            where.and(new Elt("bir_d2_0", form.getBirDate2()));
        }
        if (CommonUtil.isNotNullEmpty(form.getBirTime())) {
            where.and(new Elt("bir_d2_1", form.getBirTime()));
        }
        if (CommonUtil.isNotNullEmpty(form.getCreateTime())) {
            where.and(new Elt("create_time", form.getCreateTime()));
        }
        List<UserTest> list = userTestDao.getJbaTemplate()
                                         .queryList(select, UserTest.class, new PageInfo(1, 100, false));
        return list;
    }

    @GetMapping("/list1/{needTotalCount}")
    public Object list1(@PathVariable("needTotalCount") Boolean needTotalCount) {
        UserTest temp = new UserTest();
        List<UserTest> list = userTestDao.page(temp, UserTest.class, new PageInfo(1, 10, needTotalCount));
        return list;
    }

    @GetMapping("/count")
    public Object count() {
        UserTest user = new UserTest();
        int count = userTestDao.count(user);
        return count;
    }

    @GetMapping("/add/{count}")
    public Object addCount(@PathVariable Integer count) {
        int aThreadDealCount = 1000;
        int times = count / aThreadDealCount;
        for (int i = 0; i < times; i++) {
            CompletableFuture.runAsync(() -> {
                UserTest[] temp = new UserTest[aThreadDealCount];
                for (int j = 0; j < aThreadDealCount; j++) {
                    temp[j] = new UserTest();
                    temp[j].setAge((int) (Math.random() * 10));
                    temp[j].setName(CommonUtil.newGuid(false));
                    temp[j].setBirDate(new Date());
                    temp[j].setBirDate2(new java.sql.Date(System.currentTimeMillis()));
                    temp[j].setCreateTime(new Timestamp(System.currentTimeMillis()));
                    temp[j].setDescription("测试插入，测试插入，测试插入，测试插入测试插入");
                    temp[j].setHeight((float) (Math.random() * 180));
                    temp[j].setStatus(StatusEnum.ONLINE);
                    temp[j].setSalary(BigDecimal.valueOf(Math.random() * 8888));
                    temp[j].setWeight(Math.random() * 200);
                }
                userTestDao.batchAdd(temp);
            });
        }
        return "success";
    }

    @GetMapping("/testLog")
    public void testLog() {
        LOGGER.debug("log level is debug");
        LOGGER.info("log level is info");
        LOGGER.error("log level is error");
        LogbackLoggingSystem logbackLoggingSystem = new LogbackLoggingSystem(UserTest.class.getClassLoader());
        logbackLoggingSystem.setLogLevel(LOGGER.getName(), LogLevel.DEBUG);
        LOGGER.debug("log level is ");
        LOGGER.info("log level is ");
        LOGGER.error("log level is ");
        LOGGER.trace("log level is ");
    }

    /**
     * 不能防止sql注入
     *
     * @param name
     * @return
     */
    @GetMapping("/getUserConcat/{name}")
    @ApiImplicitParam(name = "name", paramType = "path", defaultValue = "xxxxx' or 1=1 limit 1 -- d")
    public UserTest getUserConcat(@PathVariable String name) throws UnsupportedEncodingException {
        name = URLDecoder.decode(name, "utf-8");
        return userTestDao.findByNameConcat(name);
    }

    /**
     * 能够有效的防止sql注入
     *
     * @param name
     * @return
     */
    @GetMapping("/getUser/{name}")
    @ApiImplicitParam(name = "name", paramType = "path", defaultValue = "xxxxx' or 1=1 limit 1 -- d")
    public Object getUser(@PathVariable String name) throws UnsupportedEncodingException {
        name = URLDecoder.decode(name, "utf-8");
        UserTest byName = userTestDao.findByName(name);
        if (null == byName) {
            return "不存在";
        }
        return byName;
    }

    @GetMapping("/testAlias")
    public Object testAlias() {
        List<Birthday> page = userTestDao.page(new UserTest(), Birthday.class, new PageInfo(1, 10, false));
        return page;
    }

    @GetMapping("/testIn")
    public Object testIn(@RequestParam String ids) {
        return userTestDao.testIn(ids.split("[,; ]"));
    }

}
